package sample;

import cn.hutool.core.io.resource.ClassPathResource;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.input.MouseEvent;
import javafx.stage.FileChooser;
import javafx.stage.Window;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import sample.entity.OrderDetail;
import sample.entity.Stock;
import sample.uitl.ui.ExcelUtil;
import sample.uitl.ui.MonologFXUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


public class StockController extends Window {

    public Button btn1;
    public Button btn2;
    public Button btn3;
    public TextArea textArea;
    public String duo = "";
    public String shao = "";
    public String zong = "";
    public static File fileloadr = null;


    public static FileChooser createFileChooser() {
        FileChooser chooser = new FileChooser();
        if (fileloadr != null) {
            chooser.setInitialDirectory(fileloadr);
        } else {
            chooser.setInitialDirectory(new File(System.getProperty("user.home") + File.separator + "Desktop"));
        }
        chooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("EXCL", "*.xls", "*.xlsx"),
                new FileChooser.ExtensionFilter("All FILE", "*.*")
        );
        return chooser;
    }

    public void test1(MouseEvent mouseEvent) throws IOException {
        FileChooser fileChooser = createFileChooser();
        File file = fileChooser.showOpenDialog(this);
        if (file == null) return;
        String path = file.getPath();
        fileloadr = file.getParentFile();
        duo = path;
        textArea.setText(textArea.getText() + "已选择库存表成功" + duo + "\n");
    }

    public void test2(MouseEvent mouseEvent) {
        FileChooser fileChooser = createFileChooser();
        File file = fileChooser.showOpenDialog(this);
        if (file == null) return;
        String path = file.getPath();
        fileloadr = file.getParentFile();
        shao = path;
        textArea.setText(textArea.getText() + "已选择清单成功:" + shao + "\n");
    }

    public void test3(MouseEvent mouseEvent) {
        try {
//            duo = "C:\\Users\\kingtop\\Desktop\\库存统计表.xls";
//            shao = "C:\\Users\\kingtop\\Desktop\\订单明细.xlsx";
            if (duo.equals("")) {
                MonologFXUtil.alert("没有选择库存统计表!");
                return;
            }
            if (shao.equals("")) {
                MonologFXUtil.alert("没有选择订单明细!");
                return;
            }

            ArrayList<Stock> stocks = new ArrayList<>();

            //商品名称 序号
            HashMap<String, Integer> hashMap = new HashMap<>();
            //没找到序号的商品
            String noSerialNumber = "";
            Integer susscess = 0;
            Integer error = 0;

            List<Map<Integer, Object>> maps = ExcelUtil.exclToArrayList(duo, 3);
            List<Map<Integer, Object>> maps1 = ExcelUtil.exclToArrayList(shao, 1);

            Integer serialNumber = 0;
            String name = null;
            String standard = "";

            for (int i = 0; i < maps.size(); i++) {
                Map<Integer, Object> map = maps.get(i);
                //因为是合并了的单元格 需要拆开
                if (name == null || (map.get(1) != name && !"".equals(map.get(1)))) {//第一次 或者 这一行和上一行不是合并的
                    if (map.get(0) == null || map.get(0).toString().equals("")) {
                        MonologFXUtil.alert("第" + (i + 4) + "行序号不能为空");
                        return;
                    }
                    serialNumber = Integer.valueOf(map.get(0).toString());
                    if (map.get(1) == null || map.get(1).toString().equals("")) {
                        MonologFXUtil.alert("第" + (i + 4) + "行名称不能为空");
                        return;
                    }
                    name = map.get(1).toString().trim();
                }
                if (standard == null || (map.get(2) != standard && !"".equals(map.get(2)))) {//第一次 或者 这一行和上一行不是合并的
                    standard = map.get(2).toString().trim();
                }
//                hashMap.put(name + standard, serialNumber);
                hashMap.put(name, serialNumber);//不管规格只管名称
                map.put(0, serialNumber);
                map.put(1, name);
                map.put(2, standard);
            }
            //处理清单
            ArrayList<OrderDetail> orderDetails = new ArrayList<>();
            for (int i = 0; i < maps1.size(); i++) {
                Map<Integer, Object> m = maps1.get(i);
                OrderDetail orderDetail = new OrderDetail();
                //名称
                orderDetail.setName(m.get(27).toString().trim());
                //规格
                orderDetail.setStandard(m.get(28).toString().trim());
                //拿序号
//                Integer integer = hashMap.get(orderDetail.getName() + orderDetail.getStandard());
                Integer integer = hashMap.get(orderDetail.getName());//不管规格
                if (integer == null) {
                    noSerialNumber += ((i + 2) + "、" + orderDetail.getName() + "\n");
                    error++;
                } else {
                    orderDetail.setTime(m.get(1).toString().trim());//下单时间
                    orderDetail.setNumber(new Integer(m.get(33).toString()));
                    orderDetail.setSerialNumber(integer);
                    orderDetails.add(orderDetail);
                    susscess++;
                }
            }
            //合并统一时间 同名称、同规格商品
            Map<String, Map<String, Map<String, List<OrderDetail>>>> collect1 = orderDetails.stream().collect(Collectors.groupingBy(OrderDetail::getTime
                    , Collectors.groupingBy(OrderDetail::getName
                            , Collectors.groupingBy(OrderDetail::getStandard))));
            //合并入旧数据
            collect1.forEach((k, v) -> {//时间
                v.forEach((k1, v1) -> {//名称
                    v1.forEach((k2, v2) -> {//规格
                        Map<Integer, Object> commodity = new HashMap<>();
                        commodity.put(0, v2.get(0).getSerialNumber());
                        commodity.put(1, v2.get(0).getName());
                        commodity.put(2, v2.get(0).getStandard());
                        commodity.put(3, "");
                        commodity.put(4, "");
                        commodity.put(5, "");
                        commodity.put(6, "");
                        commodity.put(7, "");
                        commodity.put(8, v2.get(0).getTime());
                        commodity.put(9, v2.size() == 1 ? v2.get(0).getNumber() : v2.stream().mapToInt(OrderDetail::getNumber).sum());
                        commodity.put(10, "");
                        commodity.put(11, "");
                        maps.add(commodity);
                    });
                });
            });

//            Map<String, Map<String, List<Map<Integer, Object>>>> collect = maps.stream()
//                    .collect(Collectors.groupingBy(k -> k.get(0).toString(),
//                            Collectors.groupingBy(k -> k.get(2).toString())));
            Map<String, List<Map<Integer, Object>>> collect = maps.stream()
                    .collect(Collectors.groupingBy(k -> k.get(0).toString()));

//            collect.forEach((k, v) -> {
//                v.forEach((k1, v1) -> {
//                    for (Map<Integer, Object> map : v1) {
//                        Stock stock = new Stock();
//                        stock.setSerialNumber(
//                                new Integer(map.get(0).toString().trim()))
//                                .setName(map.get(1).toString())
//                                .setStandard(map.get(2).toString())
//                                .setEnterTime(map.get(3).toString())
//                                .setEnterItem(map.get(4).toString())
//                                .setEnterPrice("".equals(map.get(5).toString()) ? null : new BigDecimal(map.get(5).toString()))
//                                .setEnterNumber("".equals(map.get(6).toString()) ? null : Integer.valueOf(map.get(6).toString()))
//                                .setComeTime(map.get(8).toString())
//                                .setComeNumber("".equals(map.get(9).toString()) ? null : Integer.valueOf(map.get(9).toString()))
//                                .setG1(v1.size());
//                        stocks.add(stock);
//                    }
//                });
//            });
            collect.forEach((k, v) -> {
                for (Map<Integer, Object> map : v) {
                    Stock stock = new Stock();
                    stock.setSerialNumber(
                            new Integer(map.get(0).toString().trim()))
                            .setName(map.get(1).toString())
                            .setStandard(map.get(2).toString())
                            .setEnterTime(map.get(3).toString())
                            .setEnterItem(map.get(4).toString())
                            .setEnterPrice("".equals(map.get(5).toString()) ? null : new BigDecimal(map.get(5).toString()))
                            .setEnterNumber("".equals(map.get(6).toString()) ? null : Integer.valueOf(map.get(6).toString()))
                            .setComeTime(map.get(8).toString())
                            .setComeNumber("".equals(map.get(9).toString()) ? null : Integer.valueOf(map.get(9).toString()))
                            .setG1(v.size());
                    stocks.add(stock);
                }
            });
            List<Stock> stocks1 = stocks.stream().sorted(Comparator.comparing(Stock::getSerialNumber)).collect(Collectors.toList());


            ClassPathResource cpr = new ClassPathResource("/templates/kucun.xls");
            InputStream is = cpr.getStream();
//            Workbook workbook = new XSSFWorkbook(is);//xlsx
            Workbook workbook = new HSSFWorkbook(is);//xls
            Sheet sheet = workbook.getSheetAt(0);

            //公式开始行
            Integer nameLine = 4;
            Integer numLine = 4;
            Integer line = 1;

            ArrayList<Integer> integers = new ArrayList<>();
            ArrayList<Integer> integers1 = new ArrayList<>();
            integers.add(nameLine);
            integers1.add(numLine);
            //表格开始行
            Integer begenLine = 3;

            for (int i = 0; i < stocks1.size(); i++) {
                //设置公式
                stocks1.get(i).setG(numLine);
                if (i == stocks1.size() - 1) {//是最后一个
                    if (stocks1.size() > 1) {
                        if (stocks1.get(i).getName().equals(stocks1.get(i - 1).getName())) {//和上一个名字相同
                            if (stocks1.get(i).getStandard().equals(stocks1.get(i - 1).getStandard())) {//规格是否相同
                                nameLine = numLine = nameLine + line;
                                integers.add(nameLine);
                                integers1.add(numLine);
                            }
                        }
                    }
                } else if (stocks1.get(i).getName().equals(stocks1.get(i + 1).getName())) {//和下一个名字相同
                    if (!stocks1.get(i).getStandard().equals(stocks1.get(i + 1).getStandard())) {//规格是否相同
                        numLine = nameLine + line;
                        integers1.add(numLine);
                    }
                } else {
                    nameLine = numLine = nameLine + line;
                    integers.add(nameLine);
                    integers1.add(numLine);
                    line = 0;
                }

                line++;
                Row row = sheet.getRow(i + begenLine);
                if (row == null) row = sheet.createRow(i + begenLine);

                Integer size = 0;
                List<Cell> cells = ExcelUtil.getCells(row, 12);
                cells.get(size++).setCellValue(stocks1.get(i).getSerialNumber());
                cells.get(size++).setCellValue(stocks1.get(i).getName());
                cells.get(size++).setCellValue(stocks1.get(i).getStandard());
                cells.get(size++).setCellValue(stocks1.get(i).getEnterTime());
                cells.get(size++).setCellValue(stocks1.get(i).getEnterItem());
                if (stocks1.get(i).getEnterPrice() == null) {
                    cells.get(size++).setCellValue("");
                } else {
                    cells.get(size++).setCellValue(stocks1.get(i).getEnterPrice().doubleValue());
                }
                if (stocks1.get(i).getEnterNumber() == null) {
                    cells.get(size++).setCellValue("");
                } else {
                    cells.get(size++).setCellValue(stocks1.get(i).getEnterNumber());
                }
                cells.get(size++).setCellFormula(stocks1.get(i).getEnterNumberCount());//入库总数
                cells.get(size++).setCellValue(stocks1.get(i).getComeTime());
                if (stocks1.get(i).getComeNumber() == null) {
                    cells.get(size++).setCellValue("");
                } else {
                    cells.get(size++).setCellValue(stocks1.get(i).getComeNumber());
                }
                cells.get(size++).setCellFormula(stocks1.get(i).getComeNumberCount());//出库总数
                cells.get(size++).setCellFormula(stocks1.get(i).getRemainingStock());//库存
            }
//序号、名称
            for (int i = 0; i < integers.size() - 1; i++) {
                if (integers.get(i + 1) - integers.get(i) > 1) {
                    sheet.addMergedRegion(new CellRangeAddress(integers.get(i) - 1, integers.get(i + 1) - 2, 0, 0));
                    sheet.addMergedRegion(new CellRangeAddress(integers.get(i) - 1, integers.get(i + 1) - 2, 1, 1));

                    sheet.addMergedRegion(new CellRangeAddress(integers.get(i) - 1, integers.get(i + 1) - 2, 2, 2));
                    sheet.addMergedRegion(new CellRangeAddress(integers.get(i) - 1, integers.get(i + 1) - 2, 7, 7));
                    sheet.addMergedRegion(new CellRangeAddress(integers.get(i) - 1, integers.get(i + 1) - 2, 10, 10));
                    sheet.addMergedRegion(new CellRangeAddress(integers.get(i) - 1, integers.get(i + 1) - 2, 11, 11));
                }
            }
//            //序号、名称
//            for (int i = 0; i < integers.size() - 1; i++) {
//                if(integers.get(i+1)-integers.get(i)>1){
//                    sheet.addMergedRegion(new CellRangeAddress(integers.get(i) - 1, integers.get(i + 1) - 2, 0, 0));
//                    sheet.addMergedRegion(new CellRangeAddress(integers.get(i) - 1, integers.get(i + 1) - 2, 1, 1));
//                }
//
//            }
//            //规格、入库总数、出库总数、库存
//            for (int i = 0; i < integers1.size() - 1; i++) {
//                if(integers1.get(i+1)-integers1.get(i)>1){
//                    sheet.addMergedRegion(new CellRangeAddress(integers1.get(i) - 1, integers1.get(i + 1) - 2, 2, 2));
//                    sheet.addMergedRegion(new CellRangeAddress(integers1.get(i) - 1, integers1.get(i + 1) - 2, 7, 7));
//                    sheet.addMergedRegion(new CellRangeAddress(integers1.get(i) - 1, integers1.get(i + 1) - 2, 10, 10));
//                    sheet.addMergedRegion(new CellRangeAddress(integers1.get(i) - 1, integers1.get(i + 1) - 2, 11, 11));
//                }
//            }

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH时mm分ss秒");
            String format = sdf.format(Calendar.getInstance().getTime());
            String fileName = duo.split("\\.")[0] + format + ".xls";
            FileOutputStream fileOutputStream = new FileOutputStream(fileName);
            workbook.write(fileOutputStream);
            workbook.close();
            fileOutputStream.close();

            duo = "";
            shao = "";
            zong = "";
            textArea.setText(textArea.getText() + "---------------------------------------------\n成功\n文件生成位置为:" + fileName + "   \n" +
                    "  共计成功 " + susscess + "条,失败" + error + "条.\n" + (noSerialNumber.equals("") ? "" : ("可能没有名称 可能同名称没有对应规格\n" + noSerialNumber)));
        } catch (
                Exception e) {
            MonologFXUtil.alert(e.getMessage());
            e.printStackTrace();
        }
    }

    public void test4(MouseEvent mouseEvent) {
        textArea.setText("");
    }
}
